#include "include/modbusrwparam.h"
QMutex                          ModbusRWParam::mutex;
QScopedPointer< ModbusRWParam > ModbusRWParam::instance;
ModbusRWParam&                  ModbusRWParam::getInstance() {
    if ( instance.isNull() ) {
        mutex.lock();
        if ( instance.isNull() ) { instance.reset( new ModbusRWParam() ); }
        mutex.unlock();
    }
    return *instance.data();
}
/**
 * @brief ModbusRWParam::readReadWiter
 * 读取config/ModbusRead.ini、config/ModbusWriter.ini 配置文件
 */
void ModbusRWParam::readReadWiter() {
    qDebug() << "readReadWiter";

    qDebug() << "ModbusWriter";
    if ( writerModbusInitModeMap != nullptr ) { writerModbusInitModeMap->clear(); }
    QSettings modbus_writer_param( "./config/ModbusWriter.ini", QSettings::IniFormat );
    modbus_writer_param.setIniCodec( QTextCodec::codecForName( "UTF-8" ) );
    modbus_writer_param.beginGroup( "modbus_writer" );
    for ( const QString& key : modbus_writer_param.allKeys() ) {
        if ( !key.contains( "#" ) && modbus_writer_param.value( key ).toStringList().size() == 3 ) {
            //            qDebug() << key << modbus_writer_param.value( key ).toStringList();
            int           adress      = modbus_writer_param.value( key ).toStringList().at( 0 ).toInt();
            int           value_type  = modbus_writer_param.value( key ).toStringList().at( 1 ).toInt();
            uint          data_length = modbus_writer_param.value( key ).toStringList().at( 2 ).toUInt();
            ModbusIniMode writer;
            writer.name        = new QString( key );
            writer.adress      = static_cast< quint16 >( adress );
            writer.value_type  = static_cast< quint16 >( value_type );
            writer.data_length = static_cast< quint16 >( data_length );
            writerModbusInitModeMap->insert( key, writer );
        }
    }
    modbus_writer_param.endGroup();

    qDebug() << "ModbusListWriter";

    if ( writerModbusListInitModeMap != nullptr ) { writerModbusListInitModeMap->clear(); }
    QSettings modbus_writer_list_param( "./config/ModbusListWriter.ini", QSettings::IniFormat );
    modbus_writer_list_param.setIniCodec( QTextCodec::codecForName( "UTF-8" ) );
    modbus_writer_list_param.beginGroup( "modbus_list_writer" );
    for ( const QString& key : modbus_writer_list_param.allKeys() ) {
        //        qDebug() << "ModbusListWriter key " << key;
        //        qDebug() << "value:" << modbus_writer_list_param.value( key ).toStringList();
        //        qDebug() << "value size" << modbus_writer_list_param.value( key ).toStringList().size();
        if ( !key.contains( "#" ) && modbus_writer_list_param.value( key ).toStringList().size() == 6 ) {
            //            qDebug() << key << modbus_writer_param.value( key ).toStringList();
            int               value_adress             = modbus_writer_list_param.value( key ).toStringList().at( 0 ).toInt();
            int               value_length             = modbus_writer_list_param.value( key ).toStringList().at( 1 ).toInt();
            int               control_adress           = modbus_writer_list_param.value( key ).toStringList().at( 2 ).toInt();
            int               control_take_value       = modbus_writer_list_param.value( key ).toStringList().at( 3 ).toInt();
            int               control_clear_now_value  = modbus_writer_list_param.value( key ).toStringList().at( 4 ).toInt();
            int               control_clear_back_value = modbus_writer_list_param.value( key ).toStringList().at( 5 ).toInt();
            ModbusListIniMode writer;
            writer.name                     = new QString( key );
            writer.value_adress             = static_cast< quint16 >( value_adress );
            writer.value_length             = static_cast< quint16 >( value_length );
            writer.control_adress           = static_cast< quint16 >( control_adress );
            writer.control_take_value       = static_cast< quint16 >( control_take_value );
            writer.control_clear_now_value  = static_cast< quint16 >( control_clear_now_value );
            writer.control_clear_back_value = static_cast< quint16 >( control_clear_back_value );
            writerModbusListInitModeMap->insert( key, writer );
        }
    }
    modbus_writer_list_param.endGroup();

    qDebug() << "ModbusHighFrequencyWriter";

    if ( writerModbusInitHightFrequenceyModeMap != nullptr ) { writerModbusInitHightFrequenceyModeMap->clear(); }
    QSettings modbus_writer_int_highfrequencey_param( "./config/ModbusHighFrequencyWriter.ini", QSettings::IniFormat );
    modbus_writer_int_highfrequencey_param.setIniCodec( QTextCodec::codecForName( "UTF-8" ) );
    modbus_writer_int_highfrequencey_param.beginGroup( "modbus_int_high_frequencey_writer" );
    for ( const QString& key : modbus_writer_int_highfrequencey_param.allKeys() ) {
        if ( !key.contains( "#" ) && modbus_writer_int_highfrequencey_param.value( key ).toStringList().size() == 1 ) {
            int position = modbus_writer_int_highfrequencey_param.value( key ).toStringList().at( 0 ).toInt();
            writerModbusInitHightFrequenceyModeMap->insert( key, position );
        }
    }
    modbus_writer_int_highfrequencey_param.endGroup();

    qDebug() << "ModbusRead";

    if ( readModbusIniModeMap != nullptr ) { readModbusIniModeMap->clear(); }
    QSettings modbus_read_param( "./config/ModbusRead.ini", QSettings::IniFormat );
    modbus_read_param.setIniCodec( QTextCodec::codecForName( "UTF-8" ) );
    modbus_read_param.beginGroup( "modbus_read" );
    for ( const QString& key : modbus_read_param.allKeys() ) {
        if ( !key.contains( "#" ) && modbus_read_param.value( key ).toStringList().size() == 3 ) {
            //            qDebug() << "read key:" << key;
            int  adress      = modbus_read_param.value( key ).toStringList().at( 0 ).toInt();
            int  value_type  = modbus_read_param.value( key ).toStringList().at( 1 ).toInt();
            uint data_length = modbus_read_param.value( key ).toStringList().at( 2 ).toUInt();
            if ( data_length < 1 ) {
                qDebug() << "数据长度不能小于1";
                data_length = 1;
            }
            ModbusIniMode read;
            read.name        = new QString( key );
            read.adress      = adress;
            read.value_type  = value_type;
            read.data_length = data_length;
            readModbusIniModeMap->insert( key, read );
        }
    }
    modbus_read_param.endGroup();

    printReadWiter();
}

void ModbusRWParam::printReadWiter() {
    for ( QString& key : readModbusIniModeMap->keys() ) {
        qDebug() << "name:" << readModbusIniModeMap->value( key ).name;
        qDebug() << "adress" << readModbusIniModeMap->value( key ).adress;
        qDebug() << "value_type" << readModbusIniModeMap->value( key ).value_type;
        qDebug() << "data_length" << readModbusIniModeMap->value( key ).data_length;
    }
    for ( QString& key : writerModbusInitModeMap->keys() ) {
        qDebug() << "name:" << writerModbusInitModeMap->value( key ).name;
        qDebug() << "adress" << writerModbusInitModeMap->value( key ).adress;
        qDebug() << "value_type" << writerModbusInitModeMap->value( key ).value_type;
        qDebug() << "data_length" << writerModbusInitModeMap->value( key ).data_length;
    }

    for ( QString& key : writerModbusListInitModeMap->keys() ) {
        qDebug() << "name:" << writerModbusListInitModeMap->value( key ).name;
        qDebug() << "value_adress:" << writerModbusListInitModeMap->value( key ).value_adress;
        qDebug() << "value_length:" << writerModbusListInitModeMap->value( key ).value_length;
        qDebug() << "control_adress:" << writerModbusListInitModeMap->value( key ).control_adress;
        qDebug() << "control_take_value:" << writerModbusListInitModeMap->value( key ).control_take_value;
        qDebug() << "control_clear_now_value:" << writerModbusListInitModeMap->value( key ).control_clear_now_value;
        qDebug() << "control_clear_back_value:" << writerModbusListInitModeMap->value( key ).control_clear_back_value;
    }
}

/**
 * @brief ModbusRWParam::getWriterModbusInitMode
 * @param key
 * @param initMode
 * @return true:根据key获取写寄存器ModbusIniMode,false:不存在该key
 */
bool ModbusRWParam::getWriterModbusIniMode( const QString& key, ModbusRWParam::ModbusIniMode& initMode ) {
    if ( writerModbusInitModeMap != nullptr && writerModbusInitModeMap->contains( key ) ) {
        initMode = writerModbusInitModeMap->value( key );
        return true;
    }
    return false;
}

bool ModbusRWParam::getWriterModbusListIniMode( const QString& key, ModbusRWParam::ModbusListIniMode& initMode ) {
    if ( writerModbusListInitModeMap != nullptr && writerModbusListInitModeMap->contains( key ) ) {
        initMode = writerModbusListInitModeMap->value( key );
        return true;
    }
    return false;
}

bool ModbusRWParam::getWriterModbusIntHighFrequencey( const QString& key, int& index ) {
    if ( writerModbusInitHightFrequenceyModeMap != nullptr && writerModbusInitHightFrequenceyModeMap->contains( key ) ) {
        index = writerModbusInitHightFrequenceyModeMap->value( key );
        return true;
    }
    return false;
}

/**
 * @brief ModbusRWParam::getAllReadModbusIniMode
 * @return 返回所有读寄存器ModbusIniMode
 */
QMap< QString, ModbusRWParam::ModbusIniMode >* ModbusRWParam::getAllReadModbusIniMode() {
    return readModbusIniModeMap;
}

QString ModbusRWParam::getReadKeyByAddress( const int adress ) {
    for ( QString& key : readModbusIniModeMap->keys() ) {
        if ( adress == readModbusIniModeMap->value( key ).adress ) { return *readModbusIniModeMap->value( key ).name; }
    }
    return "";
}

ModbusRWParam::ModbusRWParam() {
    readModbusIniModeMap        = new QMap< QString, ModbusIniMode >();
    writerModbusInitModeMap     = new QMap< QString, ModbusIniMode >();
    writerModbusListInitModeMap = new QMap< QString, ModbusListIniMode >();
    writerModbusInitHightFrequenceyModeMap = new QMap<QString,int>();
}
